﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

using LowLevelGraphics.ColorSpaces;
using LowLevelGraphics.Histograms;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Tries to remove fog from the actual pic
    /// This is a filter I created completely by myself
    /// If you'd like to use "DEHAZING" see there.
    /// </summary>
    public class Defog : BaseImageFilter
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Defog"/> class.
        /// </summary>
        public Defog()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Defog"/> class.
        /// </summary>
        /// <param name="_defog">The _defog.</param>
        internal Defog(Defog _defog)
        {
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            Statistics a = new Statistics(_bitmap);
            a.SortBy(PROCESSING_MODE.Luminance);
            StatisticValue a2 = a[a.Count-1];
            Color colorBrightest = a2.Color;

            bool bFound = false;

            for (int i = 0; i < a.Count; i++)
            {
                colorBrightest = a[a.Count - i - 1].Color;
                if (colorBrightest != Color.FromArgb(255, 255, 255))
                {
                    bFound = true;
                    break;
                }
            }

            if (!bFound)
            {
                return _bitmap;
            }

            double dRFactor = 255.0f / colorBrightest.R;
            double dGFactor = 255.0f / colorBrightest.G;
            double dBFactor = 255.0f / colorBrightest.B;

            Color colorMean = ColorFunctions.GetMeanValue(_bitmap);
            UnsafeBitmap bitmap = _bitmap;

            int nHeight = bitmap.Height;
            int nWidth = bitmap.Width;

            int y = 0;
            int x = 0;

            Color color = Color.Transparent;
            string sRGB = string.Empty;
            int nDistance = 0;

            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth; x++)
                {
                    color = bitmap.GetPixel(x,y);
                    HSB hsb = new HSB(color);
                    color = hsb.ToColor();
                    sRGB = ColorFunctions.RGBMaxLetters(color);
                    nDistance = ColorFunctions.Distance(Definitions.White, color);
                    if (nDistance < 210)
                    {
                        double nR = color.R * dRFactor;
                        double nG = color.G * dGFactor;
                        double nB = color.B * dBFactor;
                        if (nR > 255) nR = 255;
                        if (nG > 255) nG = 255;
                        if (nB > 255) nB = 255;
                        color = Color.FromArgb((int)nR, (int)nG, (int)nB);
                    }
                    bitmap.SetPixel(x, y, color);
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Defog(this);
        }
    }
}
